home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / utmisc1 / chktex.lha / chktex / Resource.c < prev    next >
C/C++ Source or Header  |  1996-04-30  |  13KB  |  483 lines

  1. /*
  2.  *  ChkTeX v1.4, resource file reader.
  3.  *  Copyright (C) 1995-96 Jens T. Berger Thielemann
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  Contact the author at:
  20.  *              Jens Berger
  21.  *              Spektrumvn. 4
  22.  *              N-0666 Oslo
  23.  *              Norway
  24.  *              E-mail: <jensthi@ifi.uio.no>
  25.  *
  26.  *
  27.  */
  28.  
  29. #include "ChkTeX.h"
  30.  
  31. struct WordList
  32.         Silent          = {{0L}},
  33.         Abbrev          = {{0L}},
  34.         SlowAbbrev      = {{0L}},
  35.         Linker          = {{0L}},
  36.         IJAccent        = {{0L}},
  37.         Italic          = {{0L}},
  38.         ItalCmd         = {{0L}},
  39.         UserWarn        = {{0L}},
  40.         CmdLine         = {{0L}},
  41.         PostLink        = {{0L}},
  42.         WipeArg         = {{0L}},
  43.         VerbEnvir       = {{0L}},
  44.         MathEnvir       = {{0L}},
  45.         MathRoman       = {{0L}},
  46.         TeXInputs       = {{0L}},
  47.         HyphDash        = {{0L}},
  48.         NumDash         = {{0L}},
  49.         WordDash        = {{0L}},
  50.         CenterDots      = {{0L}},
  51.         LowDots         = {{0L}},
  52.         OutFormat       = {{0L}};
  53.  
  54. struct KeyWord
  55. {
  56.     STRPTR  Name;
  57.     STRPTR  *String;          /* Either of these are set */
  58.     struct  WordList
  59.             *List;
  60. };
  61.  
  62.  
  63. struct KeyWord Keys [] =
  64. {
  65.     {"ABBREV",      NULL,       &Abbrev},
  66.     {"CENTERDOTS",  NULL,       &CenterDots},
  67.     {"CMDLINE",     NULL,       &CmdLine},
  68.     {"HYPHDASH",    NULL,       &HyphDash},
  69.     {"IJACCENT",    NULL,       &IJAccent},
  70.     {"ITALIC",      NULL,       &Italic},
  71.     {"LINKER",      NULL,       &Linker},
  72.     {"LOWDOTS",     NULL,       &LowDots},
  73.     {"MATHENVIR",   NULL,       &MathEnvir},
  74.     {"MATHROMAN",   NULL,       &MathRoman},
  75.     {"NUMDASH",     NULL,       &NumDash},
  76.     {"OUTFORMAT",   NULL,       &OutFormat},
  77.     {"POSTLINK",    NULL,       &PostLink},
  78.     {"SILENT",      NULL,       &Silent},
  79.     {"TEXINPUTS",   NULL,       &TeXInputs},
  80.     {"USERWARN",    NULL,       &UserWarn},
  81.     {"VERBENVIR",   NULL,       &VerbEnvir},
  82.     {"WIPEARG",     NULL,       &WipeArg},
  83.     {"WORDDASH",    NULL,       &WordDash},
  84.     
  85.     {"VERBCLEAR",   &VerbClear, NULL},
  86.     {NULL,          NULL,       NULL}
  87. };
  88.  
  89.  
  90. /***************************** RESOURCE HANDLING **************************/
  91.  
  92. enum Token
  93. {
  94.     tkEof   = 0x01,     /* End-of-file */
  95.     tkOpen  = 0x02,     /* { */
  96.     tkClose = 0x04,     /* } */
  97.     tkEqual = 0x08,     /* = */
  98.     tkWord  = 0x10,     /* Keyword */
  99.     tkItem  = 0x20      /* List item */
  100. };
  101.  
  102. static enum Token Expect;
  103.  
  104. enum Token ReadWord        __PROTO((STRPTR, FILE *));
  105.  
  106. static ULONG RsrcLine;
  107.  
  108.  
  109. /*
  110.  * Parses the contents of the `.chktexrc' file.
  111.  *
  112.  * Either:
  113.  *
  114.  *  Keyword { word1 word2 ... }
  115.  *
  116.  * Or:
  117.  *
  118.  *  Keyword = word1
  119.  *
  120.  */
  121.  
  122. BOOL ReadRC(const STRPTR Filename)
  123. {
  124.     STRPTR      String = "";
  125.     BOOL        Success = FALSE;
  126.     FILE        *fh;
  127.     enum Token  Token;
  128.     ULONG       Counter;
  129.  
  130.     struct WordList
  131.         *CurList = NULL;      /* Where we'll put the words we find */
  132.     STRPTR
  133.         *CurStr = NULL;
  134.  
  135.     /* Interpret incoming words as ... */
  136.     enum
  137.     {
  138.         whList,     /* List elements */
  139.         whSolo,     /* Solo elements */
  140.         whKey       /* Keywords */
  141.     } What = whKey;
  142.  
  143.     CurList = NULL;
  144.     RsrcLine = 0;
  145.     Expect = tkWord | tkEof;
  146.  
  147.     if((fh = fopen(Filename, "r")))
  148.     {
  149.         do
  150.         {
  151.             Token = ReadWord(ReadBuffer, fh);
  152.             ifn(Expect & Token)
  153.             {
  154.                 switch(Token)
  155.                 {
  156.                 case tkItem:
  157.                     String = "item";
  158.                     break;
  159.                 case tkWord:
  160.                     String = "word";
  161.                     break;
  162.                 case tkEqual:
  163.                     String = "`='";
  164.                     break;
  165.                 case tkOpen:
  166.                     String = "`{'";
  167.                     break;
  168.                 case tkClose:
  169.                     String = "`}'";
  170.                     break;
  171.                 case tkEof:
  172.                     String = "EOF";
  173.                     break;
  174.                 }
  175.                 PrintPrgErr(pmFaultFmt, Filename, RsrcLine, String);
  176.                 Token = tkEof;
  177.             }
  178.  
  179.             switch(Token)
  180.             {
  181.             case tkWord:
  182.                 for(Counter = 0;
  183.                     Keys[Counter].Name;
  184.                     Counter++)
  185.                 {
  186.                     if(!strcasecmp(ReadBuffer, Keys[Counter].Name))
  187.                     {
  188.                         if(Keys[Counter].List)
  189.                         {
  190.                             Expect = tkOpen;
  191.                             CurList = Keys[Counter].List;
  192.                         }
  193.                         else
  194.                         {
  195.                             Expect = tkEqual;
  196.                             CurStr = Keys[Counter].String;
  197.                         }
  198.                         break;
  199.                     }
  200.                 }
  201.                 if(!Keys[Counter].Name)
  202.                     PrintPrgErr(pmKeyWord, ReadBuffer, Filename);
  203.                 break;
  204.             case tkItem:
  205.                 switch(What)
  206.                 {
  207.                 case whSolo:
  208.                     ifn(*CurStr = strdup(ReadBuffer))
  209.                         PrintPrgErr(pmStrDupErr);
  210.  
  211.                     What = whKey;
  212.                     Expect = tkWord | tkEof;
  213.                     break;
  214.                 case whList:
  215.                     InsertWord(ReadBuffer, CurList);
  216.             break;
  217.         case whKey:
  218.             PrintPrgErr(pmAssert);
  219.                 }
  220.                 break;
  221.             case tkEqual:
  222.                 What = whSolo;
  223.                 Expect = tkItem;
  224.                 break;
  225.             case tkOpen:
  226.                 Expect = tkItem | tkClose;
  227.                 What = whList;
  228.                 break;
  229.             case tkClose:
  230.                 Expect = tkWord | tkEof;
  231.                 What = whKey;
  232.                 break;
  233.         case tkEof:
  234.         break;
  235.             }
  236.         } while(Token != tkEof);
  237.  
  238.         fclose(fh);
  239.     }
  240.  
  241.     return(Success);
  242. }
  243.  
  244. /*
  245.  * Reads a token from the `.chktexrc' file. Matches brackets. Uses
  246.  * ReadLine().
  247.  */
  248.  
  249. enum Token ReadWord(STRPTR Buffer, FILE *fh)
  250. {
  251.     static
  252.         STRPTR  String = NULL;
  253.     static
  254.         UBYTE   StatBuf[BUFSIZ];
  255.     enum Token Retval = tkEof;
  256.  
  257.     UWORD       Chr;
  258.  
  259.     STRPTR      Ptr = NULL;
  260.     BOOL        OnceMore = TRUE, Cont = TRUE;
  261.  
  262.     if(Buffer)
  263.     {
  264.         do
  265.         {
  266.             if(!(String && *String))
  267.             {
  268.                 if(fgets(StatBuf, BUFSIZ-1, fh))
  269.                     String = strip(StatBuf, STRP_RGT);
  270.                 RsrcLine++;
  271.             }
  272.  
  273.             Ptr = Buffer;
  274.             if((String = strip(String, STRP_LFT)))
  275.             {
  276.                 switch(Chr = *String)
  277.                 {
  278.                 case 0:
  279.                 case CMNT:
  280.                     String = NULL;
  281.                     break;
  282.  
  283.                 case QUOTE:     /* Quoted argument */
  284.                     Cont = TRUE;
  285.                     String++;
  286.  
  287.                     while(Cont)
  288.                     {
  289.                         switch(Chr = *String++)
  290.                         {
  291.                         case 0:
  292.                         case QUOTE:
  293.                             Cont = FALSE;
  294.                             break;
  295.                         case ESCAPE:
  296.                             ifn(Chr = MapChars(&String))
  297.                                 break;
  298.  
  299.                             /* FALLTHRU */
  300.                         default:
  301.                             *Ptr++ = Chr;
  302.                         }
  303.                     }
  304.                     *Ptr = 0;
  305.                     Retval = tkItem;
  306.                     OnceMore = FALSE;
  307.                     break;
  308.                 case '{':
  309.                 case '}':
  310.                 case '=':
  311.  
  312. #define IFTOK(c, ctxt, tk) if((Chr == c) && (Expect & (ctxt))) \
  313.                            { Retval = tk; break; }
  314.  
  315.                     OnceMore = FALSE;
  316.                     String++;
  317.  
  318.                     IFTOK('{', tkOpen | tkEqual, tkOpen)
  319.                     else IFTOK('=', tkOpen | tkEqual, tkEqual)
  320.                     else IFTOK('}', tkClose, tkClose)
  321.  
  322.                     String--;
  323.  
  324.                     /* FALLTHRU */
  325.                 default:        /* Non-quoted argument */
  326.                     OnceMore = FALSE;
  327.                     if(Expect & tkWord)
  328.                     {
  329.                         while(Cont)
  330.                         {
  331.                             Chr = *String++;
  332.                             if(isalpha(Chr))
  333.                                 *Ptr++ = Chr;
  334.                             else
  335.                                 Cont = FALSE;
  336.                         }
  337.                         String--;
  338.                         Retval = tkWord;
  339.                     }
  340.                     else
  341.                     {
  342.                         while(Cont)
  343.                         {
  344.                             switch(Chr = *String++)
  345.                             {
  346.                             case CMNT:
  347.                             case 0:
  348.                                 String = NULL;
  349.                                 Cont = FALSE;
  350.                                 break;
  351.                             case ESCAPE:
  352.                                 ifn(Chr = MapChars(&String))
  353.                                     break;
  354.  
  355.                                 *Ptr++ = Chr;
  356.                                 break;
  357.                             default:
  358.                                 if(!isspace(Chr))
  359.                                     *Ptr++ = Chr;
  360.                                 else
  361.                                     Cont = FALSE;
  362.                             }
  363.                         }
  364.                         Retval = tkItem;
  365.                     }
  366.  
  367.                     ifn(Buffer[0])
  368.                     {
  369.                         PrintPrgErr(pmEmptyToken);
  370.                         if(*String)
  371.                             String++;
  372.                     }
  373.                     *Ptr = 0;
  374.                     break;
  375.                 }
  376.             }
  377.             else
  378.                 OnceMore = FALSE;
  379.         } while(OnceMore);
  380.     }
  381.     return(Retval);
  382. }
  383.  
  384.  
  385.  
  386. /*
  387.  * Translates escape codes. Give it a pointer to the char after the
  388.  * escape char, and we'll return what it maps to.
  389.  */
  390.  
  391. #define MAP(a,b)        case a: Tmp = b; break;
  392.  
  393. UBYTE MapChars(STRPTR *String)
  394. {
  395.     UBYTE       Chr, Tmp = 0;
  396.     UWORD       Cnt;
  397.  
  398.     Chr = *((STRPTR) (*String)++);
  399.  
  400.     switch(tolower(Chr))
  401.     {
  402.         MAP(QUOTE, QUOTE);
  403.         MAP(ESCAPE, ESCAPE);
  404.         MAP(CMNT, CMNT);
  405.         MAP('n', '\n');
  406.         MAP('r', '\r');
  407.         MAP('b', '\b');
  408.         MAP('t', '\t');
  409.         MAP('f', '\f');
  410.         MAP('{', '{');
  411.         MAP('}', '}');
  412.         MAP('=', '=');
  413.         MAP(' ', ' ');
  414.     case 'x':
  415.         Tmp = 0;
  416.         
  417.         for(Cnt = 0; Cnt < 2; Cnt++)
  418.         {
  419.             if(isxdigit(Chr = *((*String)++)))
  420.             {
  421.                 Chr = toupper(Chr);
  422.                 Tmp = (Tmp<<4) + Chr;
  423.                 
  424.                 if(isdigit(Chr))
  425.                     Tmp -= '0';
  426.                 else
  427.                                         Tmp -= 'A' - 10;
  428.             }
  429.             else
  430.             {
  431.                 if(Chr) {
  432.                     PrintPrgErr(pmNotPSDigit, Chr, "hex");
  433.                     Tmp = 0;
  434.                 }
  435.                 break;
  436.             }
  437.         }
  438.         break;
  439.     case '0': case '1': case '2': case '3': case '4':
  440.     case '5': case '6': case '7':
  441.         
  442.         Tmp = Chr - '0';
  443.         
  444.         for(Cnt = 0; Cnt < 2; Cnt++)
  445.         {
  446.             Chr = *((*String)++);
  447.             if(within('0',Chr,'7'))
  448.                 Tmp = (Tmp * 8) + Chr - '0';
  449.             else
  450.             {
  451.                 if(Chr)
  452.                 {
  453.                     PrintPrgErr(pmNotPSDigit, Chr, "octal");
  454.                     Tmp = 0;
  455.                 }
  456.                 break;
  457.             }
  458.         }
  459.         break;
  460.     case 'd':
  461.         for(Cnt = 0; Cnt < 3; Cnt++)
  462.         {
  463.             if(isdigit(Chr = *((*String)++)))
  464.                 Tmp = (Tmp * 10) + Chr - '0';
  465.             else
  466.             {
  467.                 if(Chr)
  468.                 {
  469.                     PrintPrgErr(pmNotPSDigit, Chr, "");
  470.                     Tmp = 0;
  471.                 }
  472.                 break;
  473.             }
  474.         }
  475.         break;
  476.     default:
  477.         PrintPrgErr(pmEscCode, ESCAPE, Chr);
  478.     }
  479.     return(Tmp);
  480. }
  481.  
  482.  
  483.